package com.itboye.ihomebank.zjtlcb.lnd.livenessdetector.utils.security;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.itboye.ihomebank.zjtlcb.lnd.livenessdetector.utils.MD5Util;


/**
 * 说明：{加签验签加密解密工具类}
 * 作者：yc
 * 邮箱：ycheng.dream@qq.com
 * Data:2018/3/6
 */
public class SecurityUtil {

    public static String secretKey;

    private static String reqData;
    private static String rspData;
    private static String seqNo;
    private static String appAccessToken;
    private static String encryptMethod;
    private static String signMethod;

    public static void setSecretKey(String secretKey) {
        SecurityUtil.secretKey = secretKey;
    }

    public static String toJson(String json) {
        try {
            JSONObject jsonObject = JSONObject.parseObject(json, Feature.OrderedField);
            if (regex(jsonObject) == null) {
                reqData = jsonObject.getString("reqData");
                seqNo = jsonObject.getString("seqNO");
                appAccessToken = jsonObject.getString("appAccessToken");
                encryptMethod = jsonObject.getString("encryptMethod").toLowerCase();
                signMethod = jsonObject.getString("signMethod").toLowerCase();

                //加签
                String signReqData = addSign(reqData + seqNo + secretKey);
                jsonObject.put("sign", signReqData);

                //加密
                String encryptReqData = addEncrypt(seqNo, reqData);
                jsonObject.put("reqData", encryptReqData);
                return jsonObject.toJSONString();
            } else {
                return regex(jsonObject);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return "json格式有误";
        }
    }

    public static String parseJson(String json) {
        try {
            JSONObject jsonObject = JSONObject.parseObject(json);
            if (regex(jsonObject) == null) {
                rspData = jsonObject.getString("rspData");
                seqNo = jsonObject.getString("seqNO");
                encryptMethod = jsonObject.getString("encryptMethod").toLowerCase();
                signMethod = jsonObject.getString("signMethod").toLowerCase();

                //解密
                String decryptReqData = decrypt(seqNo, rspData);
                if (decryptReqData != null) {
                    rspData = decryptReqData;
                    jsonObject.put("rspData", JSON.parseObject(decryptReqData, Feature.OrderedField));
                } else {
                    return "解密失败";
                }
                //验签
                String sign = jsonObject.getString("sign");
                if (regexSign(sign, rspData, seqNo)) {
                    return jsonObject.toJSONString();
                } else {
                    return "验签失败";
                }
            } else {
                return regex(jsonObject);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return "json格式有误";
        }
    }

    private static String regex(JSONObject jsonObject) {
        String errorMsg = null;
        if (secretKey.equals("") || secretKey.length() == 0) {
            errorMsg = "缺少secretKey";
        }
        if (!jsonObject.containsKey("reqData") && !jsonObject.containsKey("rspData")) {
            errorMsg = "缺少reqData参数";
        }
        if (!jsonObject.containsKey("seqNO")) {
            errorMsg = "缺少seqNo参数";
        }
        if (!jsonObject.containsKey("appAccessToken") && appAccessToken != null && appAccessToken.length() == 0) {
            errorMsg = "缺少appAccessToken参数";
        }
        if (!jsonObject.containsKey("encryptMethod")) {
            errorMsg = "缺少encryptMethod参数";
        }
        if (!jsonObject.containsKey("signMethod")) {
            errorMsg = "缺少signMethod参数";
        }
        return errorMsg;
    }

    /**
     * reqData加签
     *
     * @param signStr 待加签字符串
     */
    public static String addSign(String signStr) {
        if ("hmac_sha1".equals(signMethod)) {
            try {
                return new Hmac().encrypt(secretKey, signStr);
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else if ("md5".equals(signMethod)) {
            return MD5Util.md5_(signStr);
        }
        return "缺少必要参数";
    }

    /**
     * reqData加密
     *
     * @param reqData 待加密字符串
     * @return
     */
    public static String addEncrypt(String seqNo, String reqData) {
        if (encryptMethod.equals("aes") && reqData.length() > 0) {
            return AESCipher.encrypt(reqData, MD5Util.md5_(seqNo + appAccessToken + secretKey));
        }
        return "加密失败";
    }

    /**
     * 解密
     *
     * @param seqNo
     * @param rspData
     * @return
     */
    public static String decrypt(String seqNo, String rspData) {
        if (encryptMethod.equals("aes") && rspData.length() > 0) {
            try {
                rspData = AESCipher.decrypt(rspData, MD5Util.md5_(seqNo + appAccessToken + secretKey));
                return rspData;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * 验签
     *
     * @param signData
     * @param seqNo
     * @return
     */
    public static boolean regexSign(String sign, String rspData, String seqNo) {
        String mySign = addSign(rspData + seqNo + secretKey);
        if (sign.equals(mySign)) {
            return true;
        }
        return false;
    }
}
